package com.vendar.quicknote;

import com.vendar.quicknote.R;
import com.vendar.email.EMailAccount;
import com.vendar.oauth.OAuthSinaWeibo;
import com.vendar.oauth.OAuthAccount;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class StartActivity extends Activity {
	//note operation definitions
	static final int NEW_NOTE_REQ 		= 1;
	static final int EDIT_NOTE_REQ 		= 2;
	static final int DELETE_NOTE_REQ 	= 3;
	
	//option MENU definitions
	static final int OPTION_MENU_ITEM_CREATE 	= 0;
	static final int OPTION_MENU_ITEM_EXIT 		= 1;
	
	static final int CONTEXT_MENU_ITEM_SENDMESSAGE	= 0;
	static final int CONTEXT_MENU_ITEM_SENDEMAIL 	= 1;
	static final int CONTEXT_MENU_ITEM_SENDWEIBO 	= 2;
	static final int CONTEXT_MENU_ITEM_ADDCALENDAR 	= 3;
	static final int CONTEXT_MENU_ITEM_DELETE 		= 4;
	
	private ListView mNoteListView = null;
	
	private NoteDbManager mNoteDataMgr = null;
	private long mSelectedId = -1;
	private int mSelectedPosition = -1;
	
	private AccountDbManager mAccountDataMgr = null;
	
	//initialization
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        onRestoreInstanceState(savedInstanceState);
        Setup();
    }
    
    @Override
    public void onSaveInstanceState(Bundle state){
    	state.putLong("select_id", mSelectedId);
    	state.putInt("select_position", mSelectedPosition);
    }
    
    @Override
    public void onRestoreInstanceState(Bundle state){
    	if( state == null ) return ;
    	super.onRestoreInstanceState(state);
        mSelectedId = state.getLong("select_id");
        mSelectedPosition = state.getInt("select_position");
    }
    
    @Override
    public void onNewIntent(Intent intent){
    	CheckInitData(intent);
    }
    
    //setup
    private void Setup()
    {
        mNoteListView = (ListView)findViewById(R.id.noteList);
    	this.registerForContextMenu(mNoteListView);
        //clicked edit note
        mNoteListView.setOnItemClickListener(new OnItemClickListener(){
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				EditNote(position, id);
			}
        });
        
        //long click menu
        mNoteListView.setOnItemLongClickListener(new OnItemLongClickListener() {
			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View view,
					int position, long id) {
				StartActivity.this.mSelectedId = id;
				StartActivity.this.mSelectedPosition = position;
				return false;//so we can get a context menu
			}
		});
        
        //read data
        mNoteDataMgr = new NoteDbManager(this);
        mAccountDataMgr = new AccountDbManager(this);
        if(getIntent()!= null && getIntent().getExtras()!=null)
        {
        	String note = getIntent().getExtras().getString("note");
        	if(note != null)
        	{
        		mNoteDataMgr.CreateNote(note);
        	}
        }
    	ReMappingData();
    	CheckInitData(getIntent());
    }
    
    private void CheckInitData(Intent intent){
    	Bundle extras = intent.getExtras();
    	if( extras == null ) return ;
    	
    	//check note editing
    	if( mSelectedId>=0 && extras.getString("content")!=null){
    		mNoteDataMgr.UpdateNote(mSelectedId, extras.getString("content"));
    	}

		//we got oauth result!
    	boolean authed = mAccountDataMgr.SaveOAuthAccount(
    			extras.getString("vendor"),
    			extras.getString("user_id"), 
    			extras.getString("access_token"), 
    			extras.getString("access_secret"));
    	if( authed ){
    		ReqSendSinaWeibo();
    	}
    	
    	//we got email account!
    	boolean newemail = mAccountDataMgr.SaveEMailAccount(
    			extras.getString("username"), 
    			extras.getString("password"), 
    			extras.getString("smtp_host"), 
    			extras.getString("smtp_port"));
    	if( newemail ){
    		ReqSendEmail();
    	}
    }
    
    //pop context menu
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo){
    	menu.setHeaderTitle(R.string.select_operation);
    	menu.setHeaderIcon(R.drawable.notebook);
    	menu.add(0, CONTEXT_MENU_ITEM_SENDMESSAGE,	0, R.string.send_message);
    	menu.add(0, CONTEXT_MENU_ITEM_SENDEMAIL, 	0, R.string.send_email);
    	menu.add(0, CONTEXT_MENU_ITEM_SENDWEIBO, 	0, R.string.send_weibo);
    	menu.add(0, CONTEXT_MENU_ITEM_ADDCALENDAR, 	0, R.string.add_calendar);
    	menu.add(0, CONTEXT_MENU_ITEM_DELETE, 		0, R.string.delete);
    }
    
    @Override
    public boolean onContextItemSelected(MenuItem item){
    	switch(item.getItemId()){
    	case CONTEXT_MENU_ITEM_SENDMESSAGE:
    		StartActivity.this.ReqSendMessage();
    		break;
    	case CONTEXT_MENU_ITEM_SENDEMAIL:
    		StartActivity.this.ReqSendEmail();
    		break;
    	case CONTEXT_MENU_ITEM_SENDWEIBO:
    		StartActivity.this.ReqSendSinaWeibo();
    		break;
    	case CONTEXT_MENU_ITEM_ADDCALENDAR:
    		StartActivity.this.ReqAddCalendar();
    		break;
    	case CONTEXT_MENU_ITEM_DELETE:
			StartActivity.this.ReqDelete();
    		break;
    	default: break;
    	}
    	return true;
    }

    //Option Menu
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, OPTION_MENU_ITEM_CREATE, 0, R.string.create);
		menu.add(0, OPTION_MENU_ITEM_EXIT, 0, R.string.exit);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch( item.getItemId() )
		{
		case OPTION_MENU_ITEM_CREATE:
			CreateNewNote();
			break;
		case OPTION_MENU_ITEM_EXIT:
			this.finish();
			System.exit(0);
			break;
		default: break;
		}
		return true;
	}
	
	//action response.
    @Override
    protected void onActivityResult(int reqCode,int resCode,Intent data)
    {
    	if( data == null || data.getExtras() == null )return ;
    	switch( reqCode )
    	{
    	case NEW_NOTE_REQ:
    		if( resCode == RESULT_OK ){
    			String note = data.getExtras().getString("note");
    			if (note != null && note.length()>0){
    				mNoteDataMgr.CreateNote(note);
    				ReMappingData();
    			}
    		}
    		break;
    	case EDIT_NOTE_REQ:
    		if( resCode == RESULT_OK ){
    			String note = data.getExtras().getString("note");
    			long id = data.getExtras().getLong("id");
    			if(note != null && note.length() > 0){
    				mNoteDataMgr.UpdateNote(id, note);
    			}else{
        			mNoteDataMgr.DeleteNote(id);
    			}
       			ReMappingData();
    		}
    		break;
    	case DELETE_NOTE_REQ:
    		if( resCode == RESULT_OK ){
    			long id = data.getExtras().getLong("id");
    			DeleteNote(id);
    		}
    		break;
    	default: break;
    	}
    }
    
    //create a note
    private void CreateNewNote(){
		Intent it = new Intent();
		it.setClass(StartActivity.this, NoteEditor.class);
		startActivityForResult(it, StartActivity.NEW_NOTE_REQ);
    }
    
    //edit note
    private void EditNote(int position,long id){
    	Intent it = new Intent();
    	it.setClass(StartActivity.this, NoteEditor.class);
    	
    	Bundle extras = new Bundle();
    	extras.putLong("id",id);
    	Cursor cur = mNoteDataMgr.GetNotes();
    	cur.moveToPosition(position);
    	extras.putString("note", cur.getString(cur.getColumnIndexOrThrow(
    			NoteDbManager.KEY_CONTENT)));
    	it.putExtras(extras);
    	startActivityForResult(it, StartActivity.EDIT_NOTE_REQ);
    }
    
    //delete a note
    private boolean DeleteNote(long id){
		mNoteDataMgr.DeleteNote(id);
		ReMappingData();
		return true;
    }
    
    //send as short message
    private boolean ReqSendMessage(){
    	Intent intent = new Intent();
    	intent.setClass(StartActivity.this,SendMessageActivity.class);
    	
    	Bundle extras = new Bundle();
    	Cursor cur = mNoteDataMgr.GetNotes();
    	cur.moveToPosition(mSelectedPosition);
    	extras.putLong("id",mSelectedId); //we need a feedback
    	extras.putString("content", cur.getString(cur.getColumnIndexOrThrow(
    			NoteDbManager.KEY_CONTENT)));
    	
    	intent.putExtras(extras);
    	startActivityForResult(intent, EDIT_NOTE_REQ);
    	return true;
    }
    
    private boolean AddEMailAccount(){
    	Intent intent = new Intent();
    	intent.setClass(StartActivity.this, AddEMailAccountActivity.class);
    	startActivity(intent);
    	return true;
    }
    
    private EMailAccount CheckEMailAccount(){
    	EMailAccount account = null;
    	//check is there any account exists?
    	Cursor res = mAccountDataMgr.RetrieveEMailAccount();
    	
    	if( res == null || res.getCount()<=0 ) {
    		AlertDialog.Builder builder = new AlertDialog.Builder(this);
    		builder.setMessage(R.string.first_email_require_account);
    		builder.setPositiveButton(R.string.ok, new OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					AddEMailAccount();
					dialog.dismiss();
				}
			});
    		builder.setNegativeButton(R.string.cancel, new OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
				}
			});
    		builder.create().show();
    		return null;
    	}
    	
    	account = new EMailAccount();
    	account.UserName = res.getString(res.getColumnIndexOrThrow(AccountDbManager.KEY_EMAIL));
    	account.Password = res.getString(res.getColumnIndexOrThrow(AccountDbManager.KEY_PASSWORD));
    	account.SmtpHost = res.getString(res.getColumnIndexOrThrow(AccountDbManager.KEY_SMTP_HOST));
    	account.SmtpPort = res.getString(res.getColumnIndexOrThrow(AccountDbManager.KEY_SMTP_PORT));
    	return account;
    }
    
    //send selected note through email
    private boolean ReqSendEmail(){
    	EMailAccount account = CheckEMailAccount();
    	if( account == null ){
    		return false;
    	}
    	
    	//we got an account!
    	Cursor cur = mNoteDataMgr.GetNote(mSelectedId);
    	if( cur == null || cur.getCount()<1 ){
    		return false;
    	}
    	
    	Bundle extras = new Bundle();
    	extras.putString("username", account.UserName);
    	extras.putString("password", account.Password);
    	extras.putString("smtp_host", account.SmtpHost);
    	extras.putString("smtp_port", account.SmtpPort);
    	extras.putString("content",cur.getString(cur.getColumnIndexOrThrow(NoteDbManager.KEY_CONTENT)));
    	
    	Intent intent = new Intent();
    	intent.setClass(StartActivity.this, SendEMailActivity.class);
    	intent.putExtras(extras);
    	startActivity(intent);
    	return true;
    }
    
    //TODO maybe we shall pack the check&tweet functions together into a class...
    private OAuthAccount CheckSinaWeiboAccount(){
    	OAuthAccount userinfo = null;
    	//check is there any account exists?
    	Cursor res = mAccountDataMgr.RetrieveOAuthAccount(OAuthSinaWeibo.WEIBO_VENDOR);
    	
    	if ( res == null || res.getCount()<=0 ){
    		AlertDialog.Builder builder = new AlertDialog.Builder(this);
    		builder.setMessage(R.string.first_sinaweibo_require_oauth);
    		builder.setPositiveButton(R.string.ok, new OnClickListener(){
				@Override
				public void onClick(DialogInterface dialog, int which) {
					ReqSinaWeiboAuth();
					dialog.dismiss();
				}
    		});
    		builder.setNegativeButton(R.string.cancel, new OnClickListener(){
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
				}
    		});
    		
    		builder.create().show();
    		return null; //we got new account at onNewIntent function!
    	}
    	
		userinfo = new OAuthAccount();
		userinfo.UserId = res.getString(res.getColumnIndexOrThrow(AccountDbManager.KEY_USERID));
		userinfo.AccessToken = res.getString(res.getColumnIndexOrThrow(AccountDbManager.KEY_TOKEN));
		userinfo.AccessSecret = res.getString(res.getColumnIndexOrThrow(AccountDbManager.KEY_SECRET));
    	return userinfo;
    }
    
    private void ReqSinaWeiboAuth(){
    	Intent intent = new Intent();
    	Bundle extras = new Bundle();
    	extras.putString("vendor", OAuthSinaWeibo.WEIBO_VENDOR);
    	intent.putExtras(extras);
    	intent.setClass(StartActivity.this, OAuthActivity.class);
    	startActivity(intent);
    }
    
    //send selected note to sina weibo
    private boolean ReqSendSinaWeibo(){
    	//check up sina weibo account auth
    	OAuthAccount userinfo = CheckSinaWeiboAccount();
    	if ( userinfo == null ){
    		return false;
    	}

		//we got it!
    	Cursor cur = mNoteDataMgr.GetNote(mSelectedId);
    	if( cur == null || cur.getCount()<1 ){
    		return false;
    	}
    	
    	Bundle extras = new Bundle();
    	extras.putString("user_id", userinfo.UserId);
    	extras.putString("access_token", userinfo.AccessToken);
    	extras.putString("access_secret", userinfo.AccessSecret);
    	extras.putString("content", cur.getString(cur.getColumnIndexOrThrow(
    			NoteDbManager.KEY_CONTENT)));
    	
    	Intent intent = new Intent();
    	intent.setClass(StartActivity.this, TweetWeiboActivity.class);
    	intent.putExtras(extras);
    	startActivity(intent);
    	return true;
    }
    
    //TODO:Add to Calendar
    private boolean ReqAddCalendar(){
    	return true;
    }
    
    private boolean ReqDelete(){
    	AlertDialog.Builder ab = new AlertDialog.Builder(StartActivity.this);
		//okay
		ab.setTitle(R.string.delete_note_confirm);
		ab.setPositiveButton(R.string.ok, new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				if( DeleteNote(mSelectedId) ){
					Toast.makeText(StartActivity.this, R.string.delete_succeed, 200).show();
				}
			}
		});
		//cancel
		ab.setNegativeButton(R.string.cancel, null);
		ab.create().show();
    	return true;
    }
    
    //reset note data mapping
    private void ReMappingData()
    {
    	String []from = new String[]{NoteDbManager.KEY_CONTENT,NoteDbManager.KEY_DATE};
    	int []to = new int[]{R.id.note_content,R.id.note_date};
    	
    	SimpleCursorAdapter notes=new SimpleCursorAdapter(this, R.layout.note_item, mNoteDataMgr.GetNotes(), from, to);
    	mNoteListView.setAdapter(notes);
    }
}
